# -*- coding: utf-8 -*-

import os,logging,re,shutil
from .. import config as C
from .. import utils
from ..utils import fs
from ..utils import py
from ..build.caches.file_cache import FileCache

class LangPublisher:
	'''
		语言发布器
	'''
	def __init__(self):
		self._config = utils.getConfig()
		self._publishForce = py.getDictPath(self._config, 'publish.force', False)
		self._publishTarget = py.getDictPath(self._config, 'publish.target', [])
		
	def collectFiles(self, buildPackPath):
		'''
			收集语言文件
		'''
		files = fs.globFiles([ r'**/*' ], os.path.join(buildPackPath, 'postprocess', 'langs'))
		files = [ os.path.normpath(f) for f in files if os.path.isfile(f)]
		return files

	def checkUpdate(self):
		'''
			检测更新
		'''
		updates = set()
		for pack in os.listdir(C.BUILD_CACHES_PATH):
			fileCache = FileCache(os.path.join(C.BUILD_CACHES_PATH, pack, 'publish-langs-cache.json'))
			fileCache.load()
			files = self.collectFiles(os.path.join(C.BUILD_CACHES_PATH, pack))
			if fileCache.checkFileChange(files):
				updates.add(pack)
		return updates

	def collectPackStrings(self, clientPath, pack):
		'''
			收集包的字符串
		'''
		# 测试收集文件
		def testFile(path):
			for w in [".prefab", ".fire", ".scene", ".ts", ".js", ".json"]:
				if path.endswith(w):
					return True
			return False

		# 收集文件
		def collectFiles(files, sPath):
			if os.path.isdir(sPath):
				for f in os.listdir(sPath):
					fPath = os.path.join(sPath, f)
					if os.path.isfile(fPath):
						if testFile(fPath):
							files.append(fPath)
					elif os.path.isdir(fPath):
						metaPath = fPath + ".meta"
						if os.path.isfile(metaPath):
							metaConf = py.readJson(metaPath)
							isBundle = py.getDictPath(metaConf, "userData.isBundle", False)
							bundleName = py.getDictPath(metaConf, "userData.bundleName", None)
							if isBundle and bundleName != pack:
								continue
						collectFiles(files, fPath)
		files = []
		clientAssets = clientPath + "/assets/"
		collectFiles(files, clientAssets)
		contents = []
		for cfile in files:
			with open(cfile,"r", encoding='utf-8') as fr:
				contents.append(fr.read())
		return "".join(contents)
			
	def publishClient(self, packPath):
		'''
			发布客户端
		'''
		pack = os.path.basename(packPath)
		clientPath = utils.fullConfigPath(self._config['path']['client'])
		fontFile = os.path.join(packPath, 'postprocess', 'langs', 'fonts-index.json')
		langFile = os.path.join(packPath, 'postprocess', 'langs', 'langs.json')
		if os.path.exists(clientPath) and (os.path.exists(fontFile) or os.path.exists(langFile)):
			clientPackPath = utils.getClientPackPath(os.path.join(clientPath,'assets'), pack)
			if clientPackPath != None:
				clientAssetPath = clientPackPath + "/lcc-assets/langs/"

				if not os.path.exists(clientAssetPath):
					os.makedirs(clientAssetPath)
				fs.filterFiles(clientAssetPath, reserveReg=re.compile(r'.*[.]meta'), deleteReg=re.compile(r'.*'))
				assetIndexFile = clientAssetPath + "/indexes.json"
				indexConfig = {}

				if os.path.exists(fontFile):
					fontData = py.readJson(fontFile)
					py.mergeDict(indexConfig, fontData.get('cache',{}))
					fonts = fontData.get('fonts',{})
					for fontName in fonts:
						fontConfig = fonts[fontName]
						fontFile = fontConfig['file']
						if not os.path.isabs(fontFile):
							fontFile = os.path.join(os.path.dirname(fontData['source']), fontFile)
						fontType = fontConfig.get('type', 'REFERENCE').upper()
						destFont = os.path.normpath(os.path.join(clientAssetPath, fontName + os.path.splitext(fontFile)[-1]))
						if fontType == 'GLOBAL':
							shutil.copyfile(fontFile, destFont)
						else:
							fontTexts = fontConfig['texts'] + self._config['publish']['language']['common']
							if fontType == 'PACKAGE':
								fontTexts += self.collectPackStrings(clientPath, pack)
							utils.fontSubset(fontFile, destFont, fontTexts)
						logging.info('generate font `%s`' % destFont)
				if os.path.exists(langFile):
					langIndex = {}
					langData = py.readJson(langFile)
					for lang in langData['cache']:
						langConfig = langData['cache'][lang]
						langIndex[lang] = [ "asset://%s/lcc-assets/langs/%s" % (pack,lang) ]
						destFile = os.path.normpath(os.path.join(clientAssetPath, lang + '.json'))
						py.writeJson(langConfig, destFile, self._config.get('debug',False))
						logging.info('generate lang `%s`' % destFile)
					indexConfig['lang'] = langIndex
					# 更新前置语言
					prelangs = langData.get('prelangs')
					if prelangs:
						destFile = os.path.normpath(os.path.join(clientPackPath, 'lcc-assets','prelangs.json'))
						py.writeJson(prelangs, destFile, self._config.get('debug',False))
						logging.info('generate prelangs `%s`' % destFile)

				py.writeJson(indexConfig, assetIndexFile, self._config.get('debug',False))

				# 更新根索引文件
				rootIndexFile = os.path.join(clientPackPath, 'index-files.json')
				if os.path.exists(rootIndexFile):
					rootIndex = py.readJson(rootIndexFile)
				else:
					rootIndex = {}
				rootIndex["lang_auto"] = "asset://%s/lcc-assets/langs/indexes" % pack
				py.writeJson(rootIndex, rootIndexFile, self._config.get('debug',False))
			else:
				logging.warn('not found client pack `%s`' % pack)

		return True

	def publish(self):
		'''
			发布语言文件
		'''
		updates = self.checkUpdate()
		for f in os.listdir(C.BUILD_CACHES_PATH):
			packPath = os.path.join(C.BUILD_CACHES_PATH, f)
			if os.path.isdir(packPath):
				for target in self._publishTarget:
					if target == 'client' and (self._publishForce or (f in updates)):
						if not self.publishClient(packPath):
							return False
						fileCache = FileCache(os.path.join(packPath, 'publish-langs-cache.json'))
						fileCache.load()
						fileCache.updateFiles(self.collectFiles(packPath))
						fileCache.save()
		return True


def publish():
	return LangPublisher().publish()

